import wireformat;
class Test : Message 
{
	int[] a_;
	long  b_=10;
	string  d_;
	static ExtensionIdentifier!(uint , uint ) ww = ExtensionIdentifier!(uint , uint )(false, Type.TYPE_FIXED32, 10, false );
	uint _has_bits_[(2 + 31 ) / 32];
	bool has_bit(int index )
	{
		return (_has_bits_[index / 32] & (1u << (index % 32 ))) != 0;
	}
	void set_bit(int index )
	{
		_has_bits_[index / 32] |= (1u << (index % 32 ));
	}
	void clear_bit(int index )
	{
		_has_bits_[index / 32] &= ~(1u << (index % 32 ));
	}
	int[] a()
	{
		return a_;
	}
	int a_size()
	{
		return a_.length;
	}
	void clear_a()
	{
		a_.length = 0;
	}
	int[] mutable_a()
	{
		return a_.dup;
	}
	int a(int index )
	{
		return a_[index];
	}
	void set_a(int index, int value )
	{
		a_[index]=value;
	}
	void add_a(int value )
	{
		a_ ~=value;
	}
	long b()
	{
		return b_;
	}
	bool has_b()
	{
		return has_bit(1 );
	}
	void clear_b()
	{
		b_ =10;
		clear_bit(1 );
	}
	void set_b(long value )
	{
		set_bit(1 );
		b_ =value;
	}
	bool has_d()
	{
		return has_bit(2 );
	}
	void clear_d()
	{
		d_.length = 0;
		clear_bit(2 );
	}
	string d()
	{
		return d_;
	}
	void set_d(string value )
	{
		set_bit(2 );
		d_ =value;
	}
	byte[] Serialize()
	{
		byte[] rst;
		rst ~= toPackVarint(a_, 1, Type.TYPE_INT32 );
		if(has_b )
			rst ~= toVarint(b(), 2, Type.TYPE_SFIXED64 );
		if(has_d )
			rst ~= toByteString(d(), 3, Type.TYPE_STRING );
		else
 throw new Exception("Test_d is required, but not value" );
		rst ~= _unknown_fields;
		return rst;
	}
	static Test Deserialize(ref byte[] input )
	{
		return new Test(input );
	}
	this()
	{
		
	}
	this(ref byte[] input )
	{
		while(input.length>0 )
		{
			uint tag = GetTag(input );
			byte[] value = GetFieldValue(input, tag );
			switch(GetTagFieldNumber(tag ))
			{
				case 1:
if(GetTagWireType(tag )!=GetWireTypeForFieldType(Type.TYPE_INT32 ))
					throw new Exception("message not match" );
				int len = Decode!(uint )(value );
				byte[] vl = input[0..len];
				input =  input[len..length];
				while(vl.length>0 )
				{
					value = GetFieldValue(vl, tag );
					add_a(cast(int )Decode!(uint )(value ));
				}
				break;
				case 2:
if(GetTagWireType(tag )!=GetWireTypeForFieldType(Type.TYPE_SFIXED64 ))
					throw new Exception("message not match" );
				set_b(fromFixed!(long )(value ));
				break;
				case 3:
if(GetTagWireType(tag )!=GetWireTypeForFieldType(Type.TYPE_STRING ))
					throw new Exception("message not match" );
				set_d(cast(string )value );
				break;
				default:
 if(GetTagWireType(tag )!=WireType.WIRETYPE_LENGTH_DELIMITED )_unknown_fields ~=EncodeBuf(tag )~value ;
				else _unknown_fields ~= EncodeBuf(tag )~EncodeBuf(value.length )~value;
			}
		}
}
}
class Test1 : Message 
{
	int  cc_;
	uint _has_bits_[(1 + 31 ) / 32];
	bool has_bit(int index )
	{
		return (_has_bits_[index / 32] & (1u << (index % 32 ))) != 0;
	}
	void set_bit(int index )
	{
		_has_bits_[index / 32] |= (1u << (index % 32 ));
	}
	void clear_bit(int index )
	{
		_has_bits_[index / 32] &= ~(1u << (index % 32 ));
	}
	int cc()
	{
		return cc_;
	}
	bool has_cc()
	{
		return has_bit(1 );
	}
	void clear_cc()
	{
		clear_bit(1 );
	}
	void set_cc(int value )
	{
		set_bit(1 );
		cc_ =value;
	}
	import extension;
	mixin Ext;
	byte[] Serialize()
	{
		byte[] rst;
		if(has_cc )
			rst ~= toVarint(cc(), 1, Type.TYPE_SINT32 );
		rst ~= _unknown_fields;
		return rst;
	}
	static Test1 Deserialize(ref byte[] input )
	{
		return new Test1(input );
	}
	this()
	{
		
	}
	this(ref byte[] input )
	{
		while(input.length>0 )
		{
			uint tag = GetTag(input );
			byte[] value = GetFieldValue(input, tag );
			switch(GetTagFieldNumber(tag ))
			{
				case 1:
if(GetTagWireType(tag )!=GetWireTypeForFieldType(Type.TYPE_SINT32 ))
					throw new Exception("message not match" );
				set_cc(ZigZagDecode32(Decode!(uint )(value )));
				break;
				default:
 if(GetTagWireType(tag )!=WireType.WIRETYPE_LENGTH_DELIMITED )_unknown_fields ~=EncodeBuf(tag )~value ;
				else _unknown_fields ~= EncodeBuf(tag )~EncodeBuf(value.length )~value;
			}
		}
}
}
import std.stdio;

void main()
{
    Test ac = new Test;
    ac.add_a(1111);
    ac.add_a(2);
    ac.add_a(11);
    ac.set_b(12);
    ac.set_d("ccc");
    Test1 bc = new Test1;
    bc.set_cc(13);
    bc.SetExtension(ac.ww,9);
    byte[] tmp1 = bc._unknown_fields;
    byte[] wp = ac.Serialize();
    byte[] wp2 = bc.Serialize();
    Test dc = ac.Deserialize(wp);
    Test1 ec = bc.Deserialize(wp2);
    writefln(dc.a());
    writefln(dc.b());
    writefln(ec.cc());
    byte[] tmp2 = ec._unknown_fields;
    ec.GetExtension(ac.ww);
    writefln(ac.ww.value_);
}
